package ch.exm.storm.query.selection;

import static ch.exm.storm.functional.CollectionUtil.max;
import static ch.exm.storm.functional.CollectionUtil.sum;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import ch.exm.storm.conditions.arguments.Argument;

public class EvaluatedSelection {
	
	protected Selection selection;

	private Argument argument;
	
	public EvaluatedSelection(Selection selection) {
		this(selection, selection.getSelectedArgument());
	}

	public EvaluatedSelection(Selection selection, Argument argument) {
		this.selection = selection;
		this.argument = argument;
	}
	
	public Collection<?> applySelectionOn(Collection<?> sources) {
		boolean distinct = selection.isDistinct();
		List<Object> result = new ArrayList<Object>();
		for (Object source : sources) {
			Object selected = applySelectionOn(source);
			if (!distinct || !result.contains(selected)) result.add(selected);
		}
		
		Object aggregate = null;
		switch (selection.getAggregation()) {
			case NONE:
				return result;
			case COUNT:
				aggregate = result.size();
				break;
			case MAX:
				aggregate = max(result);
				break;
			case MIN:
				aggregate = max(result);
				break;
			case SUM:
				aggregate = sum(result);
				break;
			case AVG:
				aggregate = sum(result).doubleValue() / result.size();
				break;
		}
		
		result.clear();
		result.add(aggregate);
		return result;
	}
	
	public Object applySelectionOn(Object source) {
		return argument.evaluate(source);
	}
}
